import { getToken } from "~utils/auth";
import { isEmpty, isPlainObject } from "lodash-es";
import { create, contentType, XsHeaderImpl, RequestInterface } from "~shared/";
import { Toast } from "vant";
import router from "~/router/index";

type ResponseType = RequestInterface["responseType"];

// http://172.18.1.125:8003/trade/manager/doc.html#/default/%E5%AE%A2%E6%88%B7%E7%AE%A1%E7%90%86/customerListUsingPOST

// 接口401无需跳转登录的url
const badUrl = [
	"/trade/web/transaction/hasSubscribeQualification",
	"/trade/web/userInfo/isRecord",
	"/trade/web/transaction/process/landResourcesSequence",
	"/trade/web/transaction/hasOfferQualification",
	"/trade/web/transaction/process/getNowDate",
	"/trade/web/getUser",
];

const buildUrl = "";
// import.meta.env.VITE_APP_BASE_URL + import.meta.env.VITE_APP_BASE_URL;

const requestInstance = create({
	baseUrl: buildUrl,
	timeout: 6000,
	responseType: "json",
	// requestMode: "fetch",
	headers: {
		[contentType.contentType]: contentType.json,
	},
});

const omitNil = (objects: Dict) => {
	const keys = Object.keys(objects);
	return keys.reduce((memo, key) => {
		const v = objects[key];
		if (v !== null && typeof v !== "undefined") {
			memo[key] = v;
		}
		return memo;
	}, {});
};

const userStore = null;
requestInstance.use((req) => {
	// todo: 设置请求的token
	// todo: 响应设置，token是否过期，失效
	// req.mode = "cors";
	// console.log(req);

	if (isPlainObject(req.body)) {
		req.body = omitNil(req.body as Dict);
	}
	if (isPlainObject(req.query)) {
		req.query = omitNil(req.query as Dict);
	}

	if (userStore === null) {
		// userStore = useUserStore();
	}

	/* if (userStore.token) {
		(req.headers as XsHeaderImpl).set("token", getToken());
	} */

	return req;
});

enum ServiceCode {
	Success = 200,
	TokenInvalid = 500,
}

requestInstance.use(async (_, next) => {
	const result: any = (await next<
		any,
		ServiceStructure
	>()) as unknown as ServiceStructure;
	let ok = result.ok;

	const status = result.status;

	if (ok) {
		const code = result?.code ?? result.fetch.status;

		switch (code) {
			case ServiceCode.TokenInvalid:
				ok = false;
				break;
			case 40012:
				ok = false;
				result.message = "接口无权限，或网络错误";
				break;
			case 0:
				ok = true;
				break;
			case 9999:
				ok = false;
				break;
			default:
				ok = false;
				break;
		}

		result.ok = ok;
		result.code = code;
		return result;
	}
	try {
		// 判断登陆过期状态
		if (status === 401 && !ok && !badUrl.includes(result.response.uri)) {
			// useUserStore().resetInfo();
			router.replace("/login");
		}
		if (result?.type === "timeout" || result?.fetch?.type === "timeout") {
			Toast.fail("请求超时");
		}
	} catch (exx) {
		console.log("请求超时错误不用处理", exx);
	}

	return result;
});

const resp: ResponseType[] = ["blob", "arrayBuffer", "u8array"];

requestInstance.use(async (_, next) => {
	const result = await next();
	if (!result.ok) {
		return result;
	}

	const nextResult: ServiceStructure = {
		ok: result.ok,
		fetch: {
			status: result.status,
			message: result.message,
			headers: result.headers,
			completeConfig: result.completeConfig,
			type: result.type,
		},
		code: result.response.code ?? result.response.status,
		message: result.response.message ?? result.message,
		data: result.response.data ?? null,
	};

	if (!isEmpty(result.response.extra)) {
		nextResult.extra = result.response.extra;
	}
	if ("number, string".includes(typeof result.response.result)) {
		nextResult.data = {
			data: nextResult.data,
			reuslt: result.response.result,
		};
		if (typeof result.response.msg !== "undefined") {
			nextResult.data = {
				...result.response,
			};
		}
	}

	if (resp.includes(result.completeConfig.responseType)) {
		nextResult.data = result.response;
		nextResult.code = result.status;
	}

	return nextResult;
});

//  TODO 业务Code 与后端约定配置
export enum BusinessCode {
	// 请求成功
	SUCCESS_CODE = 200,
	// token格式错误，不是有效token
	TOKEN_FORMAT_ERROR = 9009,
	// token过期
	TOKEN_INVALID = 9010,
	// token加解密异常
	TOKEN_CRYPT_ERROR = 9011,
	// 用户没有该项目的权限
	PEOJECT_ACCESS_ERROR = 9040,
}

// 响应拦截器
// requestInstance.use((req, next) => {
// 	return next().then((response) => {
// 		// TODO
// 		switch (response.data.code) {
// 			case BusinessCode.SUCCESS_CODE:
// 				return response.data;
// 			case BusinessCode.TOKEN_INVALID:
// 				break;
// 			case BusinessCode.TOKEN_FORMAT_ERROR:
// 				break;
// 			case BusinessCode.TOKEN_CRYPT_ERROR:
// 				break;
// 			case BusinessCode.PEOJECT_ACCESS_ERROR:
// 				break;
// 			default:
// 				break;
// 		}

// 		message.error(response.data.message);
// 		return Promise.reject(response.data);
// 	});
// });

export { requestInstance };
export default requestInstance;
